/**
 * http回复封装类, 轻量级, 主要用于编写API
 * 
 * 开发者   : Marco
 * 创建时间 : 2016年7月18日, 上午9:35
 */

#ifndef __MARCOPP_HTTP_REPONSE_H__
#define __MARCOPP_HTTP_REPONSE_H__

#include "basic.h"

#include <string>
#include <time.h>

MARCOPP_NAMESPACE_BEGIN
MARCOPP_NAMESPACE_HTTP_BEGIN

// 回复状态
typedef enum {
    ok = 200,
//    created = 201,
//    accepted = 202,
//    no_content = 204,
//    multiple_choices = 300,
//    moved_permanently = 301,
//    moved_temporarily = 302,
//    not_modified = 304,
//    bad_request = 400,
//    unauthorized = 401,
//    forbidden = 403,
    not_found = 404,
    internal_server_error = 500,
//    not_implemented = 501,
//    bad_gateway = 502,
//    service_unavailable = 503
} status_type;

class reponse_impl;

/**
 * 
 */
class reponse : public basic {
public:
    explicit reponse(version_type version = version_1_1, status_type status = ok); // 默认http1.1, 状态200(OK)
    ~reponse(void);
    
    parse_result parse(char* data, int* data_len);  // 解析
    
    /**
     * 获取状态
     * @return 状态值
     */
    status_type get_status(void) const;
    
    /**
     * 设置状态
     * @param status 状态值
     */
    void set_status(status_type status);
    
    /**
     * 设置协议头中Date行, 使用当前时间
     */
    void set_cur_date(void);
    
    /**
     * 设置协议头中Data行, 使用指定的时间
     * @param timesec 时间秒数
     */
    void set_datetime(time_t timesec);
    
    /**
     * 设置协议头中Server行, 服务器名称
     * @param server_str 服务器名字符串
     */
    void set_server(const char* server_str);
    
    /**
     * 设置跳转目标地址
     * @param location_str 地址字符串
     */
    void set_location(const char* location_str);
    
    /**
     * 设置缓存时间
     * @param expires_timesec 缓存时间秒数
     */
    void set_expires(time_t expires_timesec);
    
    /**
     * 设置缓存时间, 直接指定字符串
     * @param expires_str 缓存时间字符串
     */
    void set_expires(const char* expires_str);
    
    /**
     * 生成http整个头部字符串, 包括状态行与消息报文头, 以两个\r\n\r\n结束
     * @param buf (out)内容存储区
     */
    void create_head_str(string& buf);
    int create_head_str(char* buf);    // 调用处保证足够大空间
    
    /**
     * 设置直接数据, 之后发送时不再组成http头, 正文, 而直接发送这里的内容, 完全由用户组成数据
     * 重复调用设置会释放之前的空间数据
     * @param ptr 数据地址, 需要动态申请的空间, 本类析构时使用free释放
     * @param len 数据长度
     */
    void set_direct_data(void* ptr, int len);
    
    /**
     * 获取直接数据
     * @param len (out)长度
     * @return 指针地址
     */
    void* get_direct_data(int& len);
    
    /**
     * 获取直接数据长度
     * @return 长度
     */
    int get_direct_len(void);
    
    void append_direct_data(void* ptr, int len);
    

protected:
    int create_status_str(char*buf);   // 生成状态行字符串形式, 自动添加\r\n与结束符
    
private:
    reponse_impl* impl;
};

MARCOPP_NAMESPACE_HTTP_END
MARCOPP_NAMESPACE_END
#endif /* __MARCOPP_HTTP_REPONSE_H__ */

